package com.rcd.viatornisl.android.model;

import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;

import android.util.Log;

public class FidelityManager extends BaseManager {
	
	private final String FIDELITY = "fidelities/";
	private final String FIDELITY_JSONLIST = "jsonlist/";
	private final String FIDELITY_JSONVIEW = "jsonview/";
	private final String FIDELITY_JSONADD = "jsonadd/";
	
	public FidelityManager() {
		// Setup the attributes
		this.setBaseUrl("");
	}
	
	public FidelityManager(String baseUrl) {
		// Setup the attributes
		this.setBaseUrl(baseUrl);
	}	
	
	public Fidelity getFidelity(int id) {
		// Set the right url
		String url = String.format("%s%s%s%d", this.getBaseUrl(), FIDELITY, FIDELITY_JSONVIEW, id);
		
		try {
			// Get full content JSON from a url
			JSONObject json = new JSONObject(new Scanner(new URL(url).openStream(), "UTF-8").useDelimiter("\\A").next());
			
			// Create a fidelity object
			Fidelity fidelity = new Fidelity();
			
			// Set the fidelity properties
			fidelity.setId(json.getJSONObject("Fidelity").getInt("id"));
			fidelity.setUser(this.getUser(json.getJSONObject("Fidelity").getInt("user_id")));
			fidelity.setEstablishment(this.getEstablishment(json.getJSONObject("Fidelity").getInt("establishment_id")));
			fidelity.setCreated(fidelity.loadDate(json.getJSONObject("Fidelity").getString("created")));
			fidelity.setModified(fidelity.loadDate(json.getJSONObject("Fidelity").getString("modified")));
			
			// Provide the return
			return fidelity;
		} catch (Exception exception) {
			// Log the error
			Log.e("Fidelity getFidelity(int id)", exception.getLocalizedMessage());
						
			// On error
			exception.printStackTrace();
		}
		
		// Provide the return
		return null;
	}
	
	public String setFidelity(Fidelity fidelity) {
		// Local variables
		String url = String.format("%s%s%s", this.getBaseUrl(), FIDELITY, FIDELITY_JSONADD);
		InputStream inputStream = null;
		String result = "";

		try {
			// Create HttpClient
			HttpClient httpclient = new DefaultHttpClient();

			// Create an post request object to the given URL
			HttpPost httpPost = new HttpPost(url);

			// Create an empty json string
			String json = "";

			// Build json object
			JSONObject jsonObject = new JSONObject();
			jsonObject.accumulate("title", fidelity.getUser());
			jsonObject.accumulate("title", fidelity.getEstablishment());
			jsonObject.accumulate("title", fidelity.getCreated());
			jsonObject.accumulate("title", fidelity.getModified());
			
			// Build a specific json object
			JSONObject jsonFidelity = new JSONObject();
			jsonFidelity.accumulate("Fidelity", jsonObject);

			// Convert the specific json object to string
			json = jsonFidelity.toString();

			// Set json to string entity object
			StringEntity stringEntity = new StringEntity(json);

			// Set parameters to the post request object
			httpPost.setEntity(stringEntity);

			// Set some headers on the post request object to inform server about the content type
			httpPost.setHeader("Accept", "application/json");
			httpPost.setHeader("Content-type", "application/json");

			// Perform an http post via post request object and receive its http response
			HttpResponse httpResponse = httpclient.execute(httpPost);

			// Get the http response content as an input stream
			inputStream = httpResponse.getEntity().getContent();

			// Convert the input stream to string
			if (inputStream != null)
				// Set the result as a string
				result = super.convertInputStreamToString(inputStream);
			else
				// Set the result as a string
				result = "Did not work!";
		} catch (Exception exception) {
			// Log the error
			Log.e("String setFidelity(Fidelity fidelity)", exception.getLocalizedMessage());
						
			// On error
			exception.printStackTrace();
		}

		// Provide the result
		return result;
	}
	
	public List<Fidelity> getFidelities() {
		// Set the right url
		String url = String.format("%s%s%s", this.getBaseUrl(), FIDELITY, FIDELITY_JSONLIST);
		
		try {
			// Get full content JSON from a url
			JSONArray json = new JSONArray(new Scanner(new URL(url).openStream(), "UTF-8").useDelimiter("\\A").next());

			// Create a fidelity list
			List<Fidelity> fidelities = new ArrayList<Fidelity>();
			
			// Fill the fidelities
			for (int index = 0; index < json.length(); index++) {
				// Create a fidelity object
				Fidelity fidelity = new Fidelity();
				
				// Set the fidelity properties
				fidelity.setId(json.getJSONObject(index).getJSONObject("Fidelity").getInt("id"));
				fidelity.setUser(this.getUser(json.getJSONObject(index).getJSONObject("Fidelity").getInt("user_id")));
				fidelity.setEstablishment(this.getEstablishment(json.getJSONObject(index).getJSONObject("Fidelity").getInt("establishment_id")));
				fidelity.setCreated(fidelity.loadDate(json.getJSONObject(index).getJSONObject("Fidelity").getString("created")));
				fidelity.setModified(fidelity.loadDate(json.getJSONObject(index).getJSONObject("Fidelity").getString("modified")));
				
				// Add the fidelity
				fidelities.add(fidelity);
			}
			
			// Provide the return
			return fidelities;
		} catch (Exception exception) {
			// Log the error
			Log.e("List<Fidelity> getFidelities()", exception.getLocalizedMessage());
						
			// On error
			exception.printStackTrace();
		}
		
		// Provide the return
		return null;
	}	
	
	private User getUser(int user_id) {
		try {
			// Create a manager object
			UserManager userManager = new UserManager(this.getBaseUrl());
			
			// Provide the return
			return userManager.getUser(user_id);
		} catch (Exception exception) {
			// Log the error
			Log.e("User getUser(int user_id)", exception.getLocalizedMessage());
						
			// On error
			exception.printStackTrace();
		}
		
		// Provide the return
		return null;
	}
	
	private Establishment getEstablishment(int establishment_id) {
		try {
			// Create a manager object
			EstablishmentManager establishmentManager = new EstablishmentManager(this.getBaseUrl());
			
			// Provide the return
			return establishmentManager.getEstablishment(establishment_id);
		} catch (Exception exception) {
			// Log the error
			Log.e("Establishment getEstablishment(int establishment_id)", exception.getLocalizedMessage());
						
			// On error
			exception.printStackTrace();
		}
		
		// Provide the return
		return null;
	}	
	
}
